"""
团队任务管理功能模块
实现任务的创建、分配、状态跟踪、评论等功能
"""
import uuid
from typing import List, Dict, Any, Optional
from datetime import datetime, timedelta
import logging

from .models import (
    TaskIn, TaskOut, TaskUpdate, TaskCommentIn, TaskCommentOut,
    TaskStatus, TaskPriority, UserRole
)

logger = logging.getLogger(__name__)


class TaskService:
    """任务管理服务"""
    
    def __init__(self):
        self.tasks = {}  # 模拟数据库存储
        self.comments = {}  # 模拟数据库存储
        self.task_counters = {}  # 任务计数器
    
    def create_task(self, task_data: TaskIn, creator_id: str) -> TaskOut:
        """创建任务"""
        try:
            task_id = str(uuid.uuid4())
            
            # 创建任务对象
            task = TaskOut(
                task_id=task_id,
                title=task_data.title,
                description=task_data.description,
                assignee_id=task_data.assignee_id,
                creator_id=creator_id,
                team_id=task_data.team_id,
                status=TaskStatus.PENDING,
                priority=task_data.priority,
                due_date=task_data.due_date,
                related_record_id=task_data.related_record_id,
                related_device_id=task_data.related_device_id,
                tags=task_data.tags or [],
                attachments=task_data.attachments or [],
                created_at=datetime.utcnow(),
                updated_at=datetime.utcnow(),
                completed_at=None
            )
            
            # 保存任务
            self.tasks[task_id] = task
            
            # 更新计数器
            self._update_task_counters(task_data.team_id, 'created')
            
            logger.info(f"任务创建成功: {task_id}, 标题: {task_data.title}")
            return task
            
        except Exception as e:
            logger.error(f"任务创建失败: {str(e)}")
            raise
    
    def get_task(self, task_id: str, user_id: str) -> Optional[TaskOut]:
        """获取任务详情"""
        try:
            task = self.tasks.get(task_id)
            if not task:
                return None
            
            # 检查用户权限
            if not self._check_task_access(task, user_id):
                return None
            
            return task
            
        except Exception as e:
            logger.error(f"获取任务失败: {str(e)}")
            return None
    
    def update_task(self, task_id: str, task_update: TaskUpdate, user_id: str) -> Optional[TaskOut]:
        """更新任务"""
        try:
            task = self.tasks.get(task_id)
            if not task:
                return None
            
            # 检查用户权限
            if not self._check_task_edit_permission(task, user_id):
                return None
            
            # 更新任务字段
            if task_update.title is not None:
                task.title = task_update.title
            if task_update.description is not None:
                task.description = task_update.description
            if task_update.assignee_id is not None:
                task.assignee_id = task_update.assignee_id
            if task_update.status is not None:
                old_status = task.status
                task.status = task_update.status
                # 如果状态变为已完成，设置完成时间
                if task_update.status == TaskStatus.COMPLETED and old_status != TaskStatus.COMPLETED:
                    task.completed_at = datetime.utcnow()
                # 如果状态从已完成变为其他状态，清除完成时间
                elif old_status == TaskStatus.COMPLETED and task_update.status != TaskStatus.COMPLETED:
                    task.completed_at = None
            if task_update.priority is not None:
                task.priority = task_update.priority
            if task_update.due_date is not None:
                task.due_date = task_update.due_date
            if task_update.tags is not None:
                task.tags = task_update.tags
            if task_update.attachments is not None:
                task.attachments = task_update.attachments
            
            task.updated_at = datetime.utcnow()
            
            logger.info(f"任务更新成功: {task_id}")
            return task
            
        except Exception as e:
            logger.error(f"任务更新失败: {str(e)}")
            return None
    
    def delete_task(self, task_id: str, user_id: str) -> bool:
        """删除任务"""
        try:
            task = self.tasks.get(task_id)
            if not task:
                return False
            
            # 检查用户权限
            if not self._check_task_delete_permission(task, user_id):
                return False
            
            # 删除任务
            del self.tasks[task_id]
            
            # 删除相关评论
            task_comments = [c for c in self.comments.values() if c.task_id == task_id]
            for comment in task_comments:
                del self.comments[comment.comment_id]
            
            # 更新计数器
            self._update_task_counters(task.team_id, 'deleted')
            
            logger.info(f"任务删除成功: {task_id}")
            return True
            
        except Exception as e:
            logger.error(f"任务删除失败: {str(e)}")
            return False
    
    def get_team_tasks(self, 
                      team_id: str, 
                      user_id: str,
                      status: Optional[TaskStatus] = None,
                      assignee_id: Optional[str] = None,
                      priority: Optional[TaskPriority] = None,
                      page: int = 1,
                      page_size: int = 20) -> Dict[str, Any]:
        """获取团队任务列表"""
        try:
            # 过滤任务
            filtered_tasks = []
            for task in self.tasks.values():
                if task.team_id != team_id:
                    continue
                
                # 检查用户权限
                if not self._check_task_access(task, user_id):
                    continue
                
                # 应用过滤器
                if status and task.status != status:
                    continue
                if assignee_id and task.assignee_id != assignee_id:
                    continue
                if priority and task.priority != priority:
                    continue
                
                filtered_tasks.append(task)
            
            # 排序（按创建时间倒序）
            filtered_tasks.sort(key=lambda x: x.created_at, reverse=True)
            
            # 分页
            total = len(filtered_tasks)
            start = (page - 1) * page_size
            end = start + page_size
            tasks_page = filtered_tasks[start:end]
            
            return {
                'tasks': tasks_page,
                'total': total,
                'page': page,
                'page_size': page_size,
                'total_pages': (total + page_size - 1) // page_size
            }
            
        except Exception as e:
            logger.error(f"获取团队任务失败: {str(e)}")
            return {'tasks': [], 'total': 0, 'page': page, 'page_size': page_size, 'total_pages': 0}
    
    def get_user_tasks(self, 
                      user_id: str,
                      status: Optional[TaskStatus] = None,
                      page: int = 1,
                      page_size: int = 20) -> Dict[str, Any]:
        """获取用户任务列表"""
        try:
            # 过滤任务
            filtered_tasks = []
            for task in self.tasks.values():
                # 用户创建的任务或分配给用户的任务
                if task.creator_id != user_id and task.assignee_id != user_id:
                    continue
                
                # 应用状态过滤器
                if status and task.status != status:
                    continue
                
                filtered_tasks.append(task)
            
            # 排序（按创建时间倒序）
            filtered_tasks.sort(key=lambda x: x.created_at, reverse=True)
            
            # 分页
            total = len(filtered_tasks)
            start = (page - 1) * page_size
            end = start + page_size
            tasks_page = filtered_tasks[start:end]
            
            return {
                'tasks': tasks_page,
                'total': total,
                'page': page,
                'page_size': page_size,
                'total_pages': (total + page_size - 1) // page_size
            }
            
        except Exception as e:
            logger.error(f"获取用户任务失败: {str(e)}")
            return {'tasks': [], 'total': 0, 'page': page, 'page_size': page_size, 'total_pages': 0}
    
    def add_task_comment(self, comment_data: TaskCommentIn, user_id: str) -> Optional[TaskCommentOut]:
        """添加任务评论"""
        try:
            # 检查任务是否存在
            task = self.tasks.get(comment_data.task_id)
            if not task:
                return None
            
            # 检查用户权限
            if not self._check_task_access(task, user_id):
                return None
            
            comment_id = str(uuid.uuid4())
            
            # 创建评论对象
            comment = TaskCommentOut(
                comment_id=comment_id,
                task_id=comment_data.task_id,
                user_id=user_id,
                content=comment_data.content,
                parent_comment_id=comment_data.parent_comment_id,
                created_at=datetime.utcnow(),
                updated_at=datetime.utcnow()
            )
            
            # 保存评论
            self.comments[comment_id] = comment
            
            # 更新任务时间
            task.updated_at = datetime.utcnow()
            
            logger.info(f"任务评论添加成功: {comment_id}")
            return comment
            
        except Exception as e:
            logger.error(f"任务评论添加失败: {str(e)}")
            return None
    
    def get_task_comments(self, task_id: str, user_id: str) -> List[TaskCommentOut]:
        """获取任务评论"""
        try:
            # 检查任务是否存在
            task = self.tasks.get(task_id)
            if not task:
                return []
            
            # 检查用户权限
            if not self._check_task_access(task, user_id):
                return []
            
            # 获取评论
            task_comments = [c for c in self.comments.values() if c.task_id == task_id]
            
            # 排序（按创建时间正序）
            task_comments.sort(key=lambda x: x.created_at)
            
            return task_comments
            
        except Exception as e:
            logger.error(f"获取任务评论失败: {str(e)}")
            return []
    
    def get_task_statistics(self, team_id: str, user_id: str) -> Dict[str, Any]:
        """获取任务统计信息"""
        try:
            # 获取团队任务
            team_tasks = [task for task in self.tasks.values() if task.team_id == team_id]
            
            # 计算统计信息
            total_tasks = len(team_tasks)
            pending_tasks = len([t for t in team_tasks if t.status == TaskStatus.PENDING])
            in_progress_tasks = len([t for t in team_tasks if t.status == TaskStatus.IN_PROGRESS])
            completed_tasks = len([t for t in team_tasks if t.status == TaskStatus.COMPLETED])
            rejected_tasks = len([t for t in team_tasks if t.status == TaskStatus.REJECTED])
            
            # 优先级分布
            priority_distribution = {
                'low': len([t for t in team_tasks if t.priority == TaskPriority.LOW]),
                'medium': len([t for t in team_tasks if t.priority == TaskPriority.MEDIUM]),
                'high': len([t for t in team_tasks if t.priority == TaskPriority.HIGH]),
                'urgent': len([t for t in team_tasks if t.priority == TaskPriority.URGENT])
            }
            
            # 完成率
            completion_rate = (completed_tasks / total_tasks * 100) if total_tasks > 0 else 0
            
            # 平均完成时间（简化计算）
            completed_tasks_with_time = [t for t in team_tasks if t.status == TaskStatus.COMPLETED and t.completed_at]
            avg_completion_time = 0
            if completed_tasks_with_time:
                total_time = sum((t.completed_at - t.created_at).total_seconds() for t in completed_tasks_with_time)
                avg_completion_time = total_time / len(completed_tasks_with_time) / 3600  # 转换为小时
            
            return {
                'total_tasks': total_tasks,
                'pending_tasks': pending_tasks,
                'in_progress_tasks': in_progress_tasks,
                'completed_tasks': completed_tasks,
                'rejected_tasks': rejected_tasks,
                'priority_distribution': priority_distribution,
                'completion_rate': round(completion_rate, 2),
                'avg_completion_time_hours': round(avg_completion_time, 2)
            }
            
        except Exception as e:
            logger.error(f"获取任务统计失败: {str(e)}")
            return {}
    
    def _check_task_access(self, task: TaskOut, user_id: str) -> bool:
        """检查任务访问权限"""
        # 这里应该检查用户角色和团队权限
        # 简化实现：团队成员都可以访问
        return True
    
    def _check_task_edit_permission(self, task: TaskOut, user_id: str) -> bool:
        """检查任务编辑权限"""
        # 任务创建者、分配者或管理员可以编辑
        return (task.creator_id == user_id or 
                task.assignee_id == user_id or 
                self._is_admin(user_id))
    
    def _check_task_delete_permission(self, task: TaskOut, user_id: str) -> bool:
        """检查任务删除权限"""
        # 只有任务创建者或管理员可以删除
        return (task.creator_id == user_id or self._is_admin(user_id))
    
    def _is_admin(self, user_id: str) -> bool:
        """检查是否为管理员（模拟实现）"""
        # 这里应该从数据库查询用户角色
        return False
    
    def _update_task_counters(self, team_id: str, action: str):
        """更新任务计数器"""
        if team_id not in self.task_counters:
            self.task_counters[team_id] = {
                'created': 0,
                'completed': 0,
                'deleted': 0
            }
        
        if action in self.task_counters[team_id]:
            self.task_counters[team_id][action] += 1


class TaskBoardService:
    """任务看板服务"""
    
    def __init__(self, task_service: TaskService):
        self.task_service = task_service
    
    def get_task_board(self, team_id: str, user_id: str) -> Dict[str, Any]:
        """获取任务看板数据"""
        try:
            # 按状态分组任务
            board_data = {
                'pending': [],
                'in_progress': [],
                'completed': [],
                'rejected': []
            }
            
            # 获取所有团队任务
            all_tasks = self.task_service.get_team_tasks(team_id, user_id, page_size=1000)
            
            for task in all_tasks['tasks']:
                status_key = task.status.value
                if status_key in board_data:
                    board_data[status_key].append(task)
            
            # 按优先级排序
            for status in board_data:
                board_data[status].sort(key=lambda x: (
                    x.priority == TaskPriority.URGENT,
                    x.priority == TaskPriority.HIGH,
                    x.priority == TaskPriority.MEDIUM,
                    x.priority == TaskPriority.LOW
                ), reverse=True)
            
            return board_data
            
        except Exception as e:
            logger.error(f"获取任务看板失败: {str(e)}")
            return {'pending': [], 'in_progress': [], 'completed': [], 'rejected': []}
    
    def move_task(self, task_id: str, new_status: TaskStatus, user_id: str) -> bool:
        """移动任务到新状态"""
        try:
            task_update = TaskUpdate(status=new_status)
            result = self.task_service.update_task(task_id, task_update, user_id)
            return result is not None
            
        except Exception as e:
            logger.error(f"移动任务失败: {str(e)}")
            return False